package com.easyclearance.baseutil;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.annotation.Resource;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.apache.commons.mail.HtmlEmail;
import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Repository;

import com.alibaba.fastjson2.JSON;
import com.easyclearance.entity.MailInfo;
import com.easyclearance.entity.TravInfoCode;

@Repository
public class MailUtil {

	
    private static final Logger logger = Logger.getLogger(MailUtil.class);

    @Resource
    ImgUtil imgUtil;
    
    public void sendCommonMail(String toMailAddr, MailInfo mailInfo, String mesInfo) {
        try {
            //科目
            String subject = "新加坡电子入境";
            //内容
            String message = "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title></title><style>" +
                    "*{padding: 0;margin:0;list-style: none;}" +
                    ".ww{width:700px;margin:0 auto;height:310px;border:1px solid #ccc;padding:48px 0 0 30px;}" +
                    ".tit{font-size:16px;color:#333333;font-weight: bold;margin-bottom: 35px;}" +
                    ".content{font-size:16px;color:#333333;}" +
                    ".content>.h{margin:19px 0 98px 0;overflow: hidden;}" +
                    ".content>.h>span{float:left;}" +
                    ".content>.h>.NUE{color:#ff9900;font-weight: bold;font-size:22px;float:left;}" +
                    ".content>.h>.k{margin:3px 0 0 10px;}" +
                    ".time{margin:19px 0 0 0;}" +
                    "</style></head><body><div class=\"ww\">" 
                    + mesInfo +
                    "</div>" +
                    "<div>出国宝服务团队</div>" +
                    "<div class=\"time\">" + new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date()) + "</div>" +
                    "</div></body></html>";

            // 设置SMTP服务器属性
            Properties properties = new Properties();
            properties.put("mail.smtp.host", mailInfo.getSmtpSetting());
            properties.put("mail.smtp.port", mailInfo.getSmtpPort());
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.starttls.enable", "true"); // 对于QQ邮箱，需要设置这个属性
     
            // 使用smtp身份验证
            properties.setProperty("mail.smtp.auth", "true"); // 需要请求认证
            properties.put("mail.smtp.ssl.enable", "true"); // 开启SSL
            properties.put("mail.smtp.ssl.protocols", "TLSv1.2"); // 指定SSL版本
            properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            // 创建邮件会话
            Authenticator auth = new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(mailInfo.getEmailLogin(), mailInfo.getAuthorizationCode()); // 使用授权码而不是密码登录
                }
            };
            Session mailSession = Session.getInstance(properties, auth);
     
            // 创建邮件消息
            MimeMessage messageInfo = new MimeMessage(mailSession);
            messageInfo.setFrom(toMailAddr);
            messageInfo.setSender(new InternetAddress(mailInfo.getEmailLogin())); // 设置发送者
            messageInfo.setRecipient(Message.RecipientType.TO, new InternetAddress(toMailAddr)); // 设置接收者
            messageInfo.setSubject(subject); // 设置邮件主题
            messageInfo.setContent(message, "text/html;charset=UTF-8"); // 设置邮件内容
            	
            
            // 发送邮件
            Transport.send(messageInfo);
     
            System.out.println("Email sent successfully!");
//			log.info("email send true!");
        } catch (Exception e) {
            e.printStackTrace();
//			log.error("email send error!");
        }
    }

    public TravInfoCode readMailsContent(String passportNo,MailInfo mailInfo) {

        // 设置邮件服务器地址、端口号等信息        
        String userName = mailInfo.getEmailLogin();
        String password = mailInfo.getAuthorizationCode();

        Properties p = new Properties();
        p.setProperty("mail.pop3.host", mailInfo.getPop3Setting()); // 按需要更改
        p.setProperty("mail.pop3.port", mailInfo.getPop3Port().toString());
        // SSL安全连接参数
        p.setProperty("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        p.setProperty("mail.pop3.socketFactory.fallback", "true");
        p.setProperty("mail.pop3.socketFactory.port", mailInfo.getPop3Port().toString());

        Session session = Session.getDefaultInstance(p);
        TravInfoCode travInfoCode = new TravInfoCode();
        try {
            // 取得pop3协议的邮件服务器
            Store store =  session.getStore("pop3");
            // 连接pop.qq.com邮件服务器
            store.connect(userName, password);
            //打开收件箱
            Folder folder = store.getFolder("INBOX");
            //设置仅读
            folder.open(Folder.READ_ONLY);
            //读取邮件
            Message[] messages = folder.getMessages();
            int length = messages.length;
            int index = 0;
            if (length>20) {
				index = length - 10;
			}
            for (int i = index; i < length; i++) {
                Message message = messages[i];
                if (message.getSubject().contains("Malaysia Digital Arrival Card")) {
                	Document document = Jsoup.parse(message.getContent().toString());
                	Elements tables = document.select("table");
                	if (tables.size()>1) {
						Elements trs = tables.get(1).select("tr");
						String passport = trs.get(1).select("td").get(2).text();
						if (passport.equals(passportNo)) {
							Flags flags = message.getFlags();
							flags.add(Flags.Flag.SEEN);
							message.setFlags(flags, true);
							//获取pin码
							String pins = trs.get(21).select("td").get(2).text();
							//创建pin码对象
							String idString = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date())+new Date().getTime();
							travInfoCode.setId(idString);
							travInfoCode.setCode(pins);
							travInfoCode.setPubts(new Date());
						}
					}
                }
            }
            //关闭链接
            folder.close(false);
            store.close();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return travInfoCode;
    }
    
    // 邮件协议
  	private static final String emailProtocol = "smtp";
    /**
     * 发送邮件
     *
     * @param emails  目标邮件地址
     * @param title   邮件标题
     * @param content 邮件内容
     */
    public boolean sendEmail(String content,MailInfo mailInfo) {
        // 未传收件人邮箱地址则直接返回
    	Set<String> emails = new HashSet<>();
    	emails.add(mailInfo.getToEmail());
        //科目
        String subject = "新加坡电子入境";
        //内容
        String messageString = "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title></title><style>" +
                "*{padding: 0;margin:0;list-style: none;}" +
                ".ww{width:700px;margin:0 auto;height:310px;border:1px solid #ccc;padding:48px 0 0 30px;}" +
                ".tit{font-size:16px;color:#333333;font-weight: bold;margin-bottom: 35px;}" +
                ".content{font-size:16px;color:#333333;}" +
                ".content>.h{margin:19px 0 98px 0;overflow: hidden;}" +
                ".content>.h>span{float:left;}" +
                ".content>.h>.NUE{color:#ff9900;font-weight: bold;font-size:22px;float:left;}" +
                ".content>.h>.k{margin:3px 0 0 10px;}" +
                ".time{margin:19px 0 0 0;}" +
                "</style></head><body><div class=\"ww\">" 
                + content +
                "</div>" +
                "<div>易通关服务团队</div>" +
                "<div class=\"time\">" + new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date()) + "</div>" +
                "</div></body></html>";
        try {
            // 1. 创建参数配置, 用于连接邮件服务器的参数配置
            Properties props = new Properties();
            props.setProperty("mail.transport.protocol", emailProtocol); // 使用的协议（JavaMail规范要求）
            props.setProperty("mail.smtp.host", mailInfo.getSmtpSetting()); // 指定smtp服务器地址
            props.setProperty("mail.smtp.port", mailInfo.getSmtpPort()+""); // 指定smtp端口号
            // 使用smtp身份验证
            props.setProperty("mail.smtp.auth", "true"); // 需要请求认证
            props.put("mail.smtp.ssl.enable", "true"); // 开启SSL
            props.put("mail.smtp.ssl.protocols", "TLSv1.2"); // 指定SSL版本
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            // 由于Properties默认不限制请求时间，可能会导致线程阻塞，所以指定请求时长
            props.setProperty("mail.smtp.connectiontimeout", "10000");// 与邮件服务器建立连接的时间限制
            props.setProperty("mail.smtp.timeout", "10000");// 邮件smtp读取的时间限制
            props.setProperty("mail.smtp.writetimeout", "10000");// 邮件内容上传的时间限制
            // 2. 根据配置创建会话对象, 用于和邮件服务器交互
            Session session = Session.getDefaultInstance(props);
            session.setDebug(false); // 设置为debug模式, 可以查看详细的发送log
            // 3. 创建邮件
            MimeMessage message = new MimeMessage(session);
            // 4. From: 发件人（昵称有广告嫌疑，避免被邮件服务器误认为是滥发广告以至返回失败，请修改昵称）
            message.setFrom(new InternetAddress(mailInfo.getEmailLogin(), subject, "UTF-8"));
            // 5. To: 收件人（可以增加多个收件人、抄送、密送）
            // MimeMessage.RecipientType.TO: 发送 MimeMessage.RecipientType.CC：抄送 MimeMessage.RecipientType.BCC：密送
            int size = emails.size();
            // 单个目标邮箱还是多个
            if (size == 1) {
                String email = emails.iterator().next();
                message.setRecipient(Message.RecipientType.TO, new InternetAddress(email, email, "UTF-8"));
            } else {
                InternetAddress[] addresses = new InternetAddress[emails.size()];
                int i = 0;
                for (String email : emails) {
                    addresses[i++] = new InternetAddress(email, email, "UTF-8");
                }
                message.setRecipients(MimeMessage.RecipientType.TO, addresses);
            }
            // 6. Subject: 邮件主题（标题有广告嫌疑，避免被邮件服务器误认为是滥发广告以至返回失败，请修改标题）
            message.setSubject(subject, "UTF-8");
            // 7. Content: 邮件正文（可以使用html标签）（内容有广告嫌疑，避免被邮件服务器误认为是滥发广告以至返回失败，请修改发送内容）
            message.setContent(messageString, "text/html;charset=UTF-8");
            // 8. 设置发件时间
            message.setSentDate(new Date());
            // 9. 保存设置
            message.saveChanges();
            // 10. 根据 Session 获取邮件传输对象
            Transport transport = session.getTransport();
            transport.connect(mailInfo.getEmailLogin(), mailInfo.getAuthorizationCode());
            // 11. 发送邮件, 发到所有的收件地址, message.getAllRecipients()获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
            transport.sendMessage(message, message.getAllRecipients());
            // 12. 关闭传输连接
            transport.close();
            return true;
        } catch (Exception e) {
            logger.error("发送邮件失败,系统错误！", e);
            return false;
        }
    }
    
    public List<Map<String, Object>> readUnreadMailsContent(MailInfo mailInfo,Integer total) {

        // 设置邮件服务器地址、端口号等信息
//        String host = mailInfo.getImapSetting();
        
        String userName = mailInfo.getEmailLogin();
        String password = mailInfo.getAuthorizationCode();
        
        
        Properties p = new Properties();
        p.setProperty("mail.pop3.host", mailInfo.getPop3Setting()); // 按需要更改
        p.setProperty("mail.pop3.port", mailInfo.getPop3Port().toString());
        // SSL安全连接参数
        p.setProperty("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        p.setProperty("mail.pop3.socketFactory.fallback", "true");
        p.setProperty("mail.pop3.socketFactory.port", mailInfo.getPop3Port().toString());

        Session session = Session.getDefaultInstance(p);
        List<Map<String, Object>> linkedList = new LinkedList<>();
        try {
            // 取得pop3协议的邮件服务器
            Store store = session.getStore("pop3");
            // 连接pop.qq.com邮件服务器
            store.connect(userName, password);
            //打开收件箱
            Folder folder = store.getFolder("INBOX");
            //设置仅读
            folder.open(Folder.READ_ONLY);
            //读取邮件
            Message[] messages = folder.getMessages();

        	System.out.println("-------开始---------"+messages.length);
        	
            for (int i = messages.length-1; i > 0; i--) {
            	if (linkedList.size()==total) {
					break;
				}
                Message message = messages[i];
                Map<String, Object> hashMap2 = new HashMap<>();
                System.out.println("sub:"+message.getSubject()+message.getReceivedDate());
                logger.error("读取邮箱:"+message.getSubject());
                if (message.getSubject().contains("Malaysia Digital Arrival Card")) {
                	Document document = Jsoup.parse(message.getContent().toString());
                	Elements tables = document.select("table");
                	if (tables.size()>1) {
						Elements trs = tables.get(1).select("tr");
						String guPassportNum = trs.get(1).select("td").get(2).text();
						if (!linkedList.toString().contains(guPassportNum)) {
//							logger.error("读取到护照号："+guPassportNum);
							hashMap2.put("guPassportNum", guPassportNum);

							String name = trs.get(0).select("td").get(2).text();
							hashMap2.put("name", name);
							String nationality = trs.get(2).select("td").get(2).text();
							hashMap2.put("nationality", nationality);
							String birth = trs.get(3).select("td").get(2).text();
							hashMap2.put("birth", birth);
							String sex = trs.get(4).select("td").get(2).text();
							hashMap2.put("sex", sex);
							String passportExpiry = trs.get(5).select("td").get(2).text();
							hashMap2.put("passportExpiry", passportExpiry);
							String email = trs.get(6).select("td").get(2).text();
							hashMap2.put("email", email);
							String mobile = trs.get(7).select("td").get(2).text();
							hashMap2.put("mobile", mobile);
							String arrDate = trs.get(9).select("td").get(2).text();
							hashMap2.put("arrDate", arrDate);
							String arrModel = trs.get(10).select("td").get(2).text();
							hashMap2.put("arrModel", arrModel);
							String depDate = trs.get(11).select("td").get(2).text();
							hashMap2.put("depDate", depDate);
							String embarkation = trs.get(12).select("td").get(2).text();
							hashMap2.put("embarkation", embarkation);
							String flightNum = trs.get(13).select("td").get(2).text();
							hashMap2.put("flightNum", flightNum);
							String stayAcc = trs.get(14).select("td").get(2).text();
							hashMap2.put("stayAcc", stayAcc);
							String addressMalaysia = trs.get(15).select("td").get(2).text();
							hashMap2.put("addressMalaysia", addressMalaysia);
							String postCode = trs.get(17).select("td").get(2).text();
							hashMap2.put("postCode", postCode);
							String city = trs.get(18).select("td").get(2).text();
							hashMap2.put("city", city);
							String state = trs.get(19).select("td").get(2).text();
							hashMap2.put("state", state);
							String pins = trs.get(21).select("td").get(2).text();
							hashMap2.put("pins", pins);
							
							linkedList.add(hashMap2);
						}
//									String filename = "output"+ new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
//									
//									ImgUtil.writeImage(name, guPassportNum, nationality, birth, sex, passportExpiry, email, mobile, arrDate, arrModel, depDate, embarkation, stayAcc, addressMalaysia, postCode, city, state, pins, filename);
//									
////									Map<String, Object> paramMap = new HashMap<>();
////									paramMap.put("lineKey", "goOrderInsuranceUrl");
////									paramMap.put("lineValue", "https://cdn.travbao.com/"+filename);
////									paramMap.put("goId", goId);
////	    							serveMapper.updateOrderPassInfo(paramMap);
//								}
//							}
//						}
					}
                }
            }
            //关闭链接
            folder.close(false);
            store.close();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return linkedList;
    }
    
    @SuppressWarnings("deprecation")
    public void forwardMail(String toMailAddr, String ccMailAddr, String content,String subject,MailInfo mailInfo,String[] filePath) {
//        logger.error("邮箱信息："+JSON.toJSONString(mailInfo));
    	HtmlEmail hemail = new HtmlEmail();
        try {
            String[] tos = null;
            if (toMailAddr.contains(",")) {
                String[] split = toMailAddr.split(",");
                tos = new String[split.length];
                for (int i = 0; i < split.length; i++) {
                    tos[i] = split[i];
                }
            } else {
                tos = new String[1];
                tos[0] = toMailAddr;

            }
            //需要开区ssl协议
            hemail.setSSL(true);
            hemail.setHostName(mailInfo.getSmtpSetting());
            //端口号
            hemail.setSmtpPort(mailInfo.getSmtpPort());

            BodyPart mimeBodyPart = new MimeBodyPart();
            mimeBodyPart.setContent(content, "text/html;charset=utf-8");
            
            Multipart mimeMultipart = new MimeMultipart();
            mimeMultipart.addBodyPart(mimeBodyPart);
            if (filePath.length!=0) {
                for (int i = 0; i < filePath.length; i++) {
                	mimeBodyPart = new MimeBodyPart();
                	DataSource fileDataSource = new FileDataSource(filePath[i]);
                	DataHandler dataHandler = new DataHandler(fileDataSource);
                	mimeBodyPart.setDataHandler(dataHandler);
                	mimeBodyPart.setFileName(fileDataSource.getName());
                	mimeMultipart.addBodyPart(mimeBodyPart);
				}
			}


            hemail.setCharset("UTF-8");
            hemail.addTo(tos);
            hemail.addCc(ccMailAddr);
            hemail.setFrom(mailInfo.getEmailLogin(), "出国宝客服");
            hemail.setAuthentication(mailInfo.getEmailLogin(), mailInfo.getAuthorizationCode());
            hemail.setSubject(subject);
            hemail.setMsg(content);
//            hemail.setContent(mimeMultipart);
            hemail.send();
//			log.info("email send true!");
        } catch (Exception e) {
            e.printStackTrace();
//			log.error("email send error!");
        }
    }

    
    public void sendEmail(String recipient, String subject, String content,MailInfo mailInfo,String [] filePath) throws MessagingException {
        final String username = mailInfo.getEmailLogin();
        final String password = mailInfo.getAuthorizationCode();
 
        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true"); // 对于QQ邮箱，请使用587端口
        props.put("mail.smtp.host", mailInfo.getSmtpSetting());
        props.put("mail.smtp.port", mailInfo.getSmtpPort());
 
        Session session = Session.getInstance(props,
          new javax.mail.Authenticator() {
            protected javax.mail.PasswordAuthentication getPasswordAuthentication() {
                return new javax.mail.PasswordAuthentication(username, password);
            }
          });
 
        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(mailInfo.getEmailLogin()));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
            message.setSubject(subject);
            message.setText(content);
            
            BodyPart mimeBodyPart = new MimeBodyPart();
            mimeBodyPart.setContent(content, "text/html;charset=utf-8");
            
            Multipart mimeMultipart = new MimeMultipart();
            mimeMultipart.addBodyPart(mimeBodyPart);
            if (filePath.length!=0) {
                for (int i = 0; i < filePath.length; i++) {
                	mimeBodyPart = new MimeBodyPart();
                	DataSource fileDataSource = new FileDataSource(filePath[i]);
                	DataHandler dataHandler = new DataHandler(fileDataSource);
                	mimeBodyPart.setDataHandler(dataHandler);
                	mimeBodyPart.setFileName(fileDataSource.getName());
                	mimeMultipart.addBodyPart(mimeBodyPart);
				}
			}
            message.setContent(mimeMultipart);
            Transport.send(message);
 
            System.out.println("Sent message successfully....");
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
    
    public static void main(String[] args) throws MessagingException {
    	
    	MailInfo mailInfo = new MailInfo();
    	mailInfo.setUserName("1604343069");
    	mailInfo.setEmailLogin("3677928797@qq.com");
    	mailInfo.setAuthorizationCode("fqrevvabwlhcdcai");
//    	mailInfo.setAuthorizationCode("Dmj1213…");
    	mailInfo.setImapSetting("imap.qq.com");
    	mailInfo.setSmtpSetting("smtp.qq.com");
    	mailInfo.setPop3Setting("pop.qq.com");
    	mailInfo.setSmtpPort(465);
    	mailInfo.setImapPort(993);
    	mailInfo.setPop3Port(995);
    	
    	Set<String> hashSet = new HashSet<>();
    	hashSet.add("travbao@163.com");
    	try {
//    		new MailUtil().sendEmail(hashSet,  "测试111111111","测试11111111111",mailInfo);
//    		("travbao@163.com.com", mailInfo, "测试");
//    		(hashSet,  "测试","测试",mailInfo);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
    	
//    	String [] arr = {"D:\\Program Files\\Desktop\\fsdownload\\MALE.JPEG"};
//    	forwardMail("travbao@163.com", "travbao@163.com", "test", "test", mailInfo, arr);
//    	
//    	 Map userParams = new HashMap();
//         userParams.put("mdacVisaCountry","ALL");
//         userParams.put("hdCurrLang","ms");
//         userParams.put("name","XIAO NI");
//         userParams.put("passNo","E26931367");
//         userParams.put("dob","04/10/1981");
//         userParams.put("nationality","CHN");
//         userParams.put("sex","0");
//         userParams.put("passExpDte","29/07/2024");
//         userParams.put("email","travbao@163.com");
//         userParams.put("confirmEmail","travbao@163.com");
//         userParams.put("region","86");
//         userParams.put("confirmRegion","86");
//         userParams.put("mobile","13811110516");
//         userParams.put("confirmMobile","13811110516");
//         userParams.put("arrDt","16/03/2024");
//         userParams.put("depDt","19/03/2024");
//         userParams.put("trvlMode","1");
//         userParams.put("embark","CHN");
//         userParams.put("accommodationStay","01");
//         userParams.put("accommodationAddress1","SWAN GARDEN HOTEL MELAKA, 1, JINKSB 1, TAMAN KOTA");
//         userParams.put("accommodationAddress2","");
//         userParams.put("accommodationState","01");
//         userParams.put("accommodationPostcode","80000");
//         userParams.put("accommodationCity","0100");
//         userParams.put("submitRegistration","Submit");
    	
//			String filepathString = "D:\\Program Files\\Desktop\\fsdownload\\MALE.JPEG";
//			String [] filePathArr = {filepathString};
//			MailUtil.forwardMail("travbao@163.com","travbao@163.com", JSON.toJSONString(userParams), "马来西亚订单" , mailInfo, filePathArr);
	        
        List<Map<String, Object>> readUnreadMailsContent = new MailUtil().readUnreadMailsContent(mailInfo,20);
        System.out.println(JSON.toJSON(readUnreadMailsContent));
    }
}
